﻿using DemoWebapi01.Entities;
using DemoWebapi01.Helper;
using DemoWebapi01.Models;
using DemoWebapi01.MyServices;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;

namespace DemoWebapi01.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class UserController : ControllerBase
    {
        private readonly MyDbContext _context;
        private readonly IEmailService _emailService;
        private readonly IAuthService _authService;
        private readonly IMemoryCache _cache;
        public UserController(MyDbContext context, IEmailService emailService, IMemoryCache cache, IAuthService authService)
        {
            _context = context;
            _emailService = emailService;
            _cache = cache;
            _authService = authService;
        }

        [HttpPost]
        public async Task<ActionResult<User>> NewUser(CreateUserRequest request)
        {
            // 参数验证
            if (string.IsNullOrEmpty(request.UserName) || string.IsNullOrEmpty(request.Password) || string.IsNullOrEmpty(request.Email))
            {
                return BadRequest("用户名、密码和邮箱都不能为空");
            }

            // 检查用户名是否已存在
            if (_context.Users.Any(u => u.UserName == request.UserName))
            {
                return BadRequest("用户名已存在");
            }

            // 检查邮箱是否已存在
            if (_context.Users.Any(u => u.Email == request.Email))
            {
                return BadRequest("邮箱已被使用");
            }

            // 创建新用户
            var user = new User
            {
                UserName = request.UserName,
                NickName = await CommonHelper.RandomNickName(),
                Password = CommonHelper.MD5Encrypt64(request.Password), // 注意：实际项目中应该对密码进行加密
                Email = request.Email,
                CreateTime = DateTime.UtcNow
            };

            _context.Users.Add(user);
            await _context.SaveChangesAsync();

            return Ok(user);
        }

        /// <summary>
        /// 通过角色名为用户分配角色
        /// </summary>
        [HttpPost]
        public async Task<ActionResult> AssignRoleByName(Guid userId, AssignRoleRequest request)
        {
            if (string.IsNullOrEmpty(request.RoleName))
            {
                return BadRequest("角色名不能为空");
            }

            // 查找用户
            var user = await _context.Users
                .Include(u => u.Roles)
                .FirstOrDefaultAsync(u => u.Id == userId);

            if (user == null)
            {
                return NotFound("用户不存在");
            }

            // 查找角色
            var role = await _context.Roles
                .FirstOrDefaultAsync(r => r.RoleName == request.RoleName && !r.IsDeleted);

            if (role == null)
            {
                return NotFound($"角色 '{request.RoleName}' 不存在");
            }

            // 检查用户是否已经拥有该角色
            if (user.Roles.Any(r => r.RoleName == request.RoleName))
            {
                return BadRequest($"用户已拥有角色 '{request.RoleName}'");
            }

            // 分配角色
            user.AddRole(role);

            // 更新修改信息
            user.ModifiedOn = DateTime.UtcNow;
            user.LastModifiedBy = request.OperatorName; // 记录操作人

            await _context.SaveChangesAsync();

            return Ok($"已成功将角色 '{request.RoleName}' 分配给用户{user.UserName}");
        }

        /// <summary>
        /// 通过角色名移除用户的角色
        /// </summary>
        [HttpDelete("{userId}/roles/remove")]
        public async Task<ActionResult> RemoveRoleByName(Guid userId, RemoveRoleRequest request)
        {
            if (string.IsNullOrEmpty(request.RoleName))
            {
                return BadRequest("角色名不能为空");
            }

            // 查找用户
            var user = await _context.Users
                .Include(u => u.Roles)
                .FirstOrDefaultAsync(u => u.Id == userId);

            if (user == null)
            {
                return NotFound("用户不存在");
            }

            // 查找要移除的角色
            var roleToRemove = user.Roles.FirstOrDefault(r => r.RoleName == request.RoleName);
            if (roleToRemove == null)
            {
                return BadRequest($"用户未拥有角色 '{request.RoleName}'");
            }

            // 移除角色
            user.Roles.Remove(roleToRemove);

            // 更新修改信息
            user.ModifiedOn = DateTime.UtcNow;
            user.LastModifiedBy = request.OperatorName;

            await _context.SaveChangesAsync();

            return Ok($"已成功移除用户的角色 '{request.RoleName}'");
        }

        /// <summary>
        /// 获取用户的所有角色
        /// </summary>
        [HttpGet]
        public async Task<ActionResult<List<Role>>> GetUserRoles(Guid userId)
        {
            var user = await _context.Users
                .Include(u => u.Roles)
                .FirstOrDefaultAsync(u => u.Id == userId && !u.IsDeleted);

            if (user == null)
            {
                return NotFound("用户不存在");
            }

            // 只返回未删除的角色
            var activeRoles = user.Roles.Where(r => !r.IsDeleted).ToList();
            return Ok(activeRoles);
        }

        /// <summary>
        /// 注册新用户
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult> RegisterNewUser(CreateUserRequest request)
        {
            var res = await NewUser(request);
            if (!(res.Result is OkObjectResult okRes))
            {
                return res.Result ?? BadRequest("注册失败。");
            }
            var resUser = okRes.Value as User;
            // 生成6位数验证码
            var verificationCode = Random.Shared.Next(100000, 999999).ToString();
            //设置缓存，10分钟内有效
            _cache.Set("vertifyEmail" + resUser.Id.ToString(), verificationCode, TimeSpan.FromMinutes(10));
            await _emailService.SendVerificationEmailAsync(resUser.Id.ToString(), resUser.Email, verificationCode);

            return Ok("账号注册成功，请及时激活邮箱。");
        }

        [HttpGet("verify/{userId}/{verificationCode}")]
        public async Task<ActionResult> VerifyEmail(Guid userId, string verificationCode)
        {
            var user = await _context.Users.FirstAsync(x => x.Id == userId);
            if (user == null)
            {
                return NotFound("用户不存在");
            }
            var cacheCode = _cache.Get("vertifyEmail" + userId.ToString());
            if (cacheCode == null || cacheCode.ToString() != verificationCode)
            {
                return BadRequest("验证码错误或已过期");
            }
            if (user.IsEmailVerified)
            {
                return Ok("邮箱验证成功，账号已激活,请勿重复点击。");
            }
            user.IsEmailVerified = true; // 激活邮箱
            await _context.SaveChangesAsync();

            return Ok("邮箱验证成功，账号已激活");
        }

        [HttpPost]
        public async Task<int> Test()
        {
            int a = 100;
            await _emailService.SendVerificationEmailAsync("1", "m15952480843@163.com", "1");
            return a;
        }

        [HttpPost]
        public async Task<ActionResult<LoginResponse>> Login(LoginRequest request)
        {
            // 参数验证
            if (string.IsNullOrEmpty(request.UserName) || string.IsNullOrEmpty(request.Password))
            {
                return BadRequest("用户名和密码不能为空");
            }

            // 查找用户
            var user = await _context.Users.Include(p => p.Roles)
                .FirstOrDefaultAsync(u => u.UserName == request.UserName && u.Password == CommonHelper.MD5Encrypt64(request.Password));

            if (user == null)
            {
                return Unauthorized("用户名或密码错误");
            }

            // 生成 JWT 令牌
            var token = _authService.GenerateJwtToken(user); // 

            // 返回自定义响应
            var response = new LoginResponse
            {
                Token = token,
                User = new
                {
                    Id = user.Id,
                    UserName = user.UserName,
                    NickName = user.NickName,
                    Email = user.Email,
                    RoleName = user.Roles.Count > 0 ? string.Join(',', user.Roles.Select(x => x.RoleName)) : ""
                }
            };
            return Ok(response);
        }
    }
}
